package cn.jit.ssm.intercept;

import cn.jit.ssm.annotation.SecureValid;
import cn.jit.ssm.beans.entity.JitAccount;
import cn.jit.ssm.constant.LoginState;
import cn.jit.ssm.constant.MethodType;
import cn.jit.ssm.constant.SessionKey;
import cn.jit.ssm.service.AccountService;
import cn.jit.ssm.service.ModuleService;
import cn.jit.ssm.support.JSONReturn;
import cn.jit.ssm.utils.CompareUtil;
import cn.jit.ssm.utils.ResponseUtil;
import com.alibaba.fastjson.JSON;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 对DispatcherServlet处理的请求进行拦截，检验是否登录，并且鉴权
 *
 * @author: Cecurio
 * @create: 2017-12-06 16:30
 **/
public class SecureValidInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(SecureValidInterceptor.class);

    @Autowired
    private AccountService accountService;

    @Autowired
    private ModuleService moduleService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 为了模仿实际网络中请求的速度, 这里让每一个请求的线程都睡眠50毫秒, 项目真正上线需删除
        Thread.sleep(50);

        String uri = request.getRequestURI();
        logger.info("访问的URI是==> " + uri);

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        logger.info("方法所在类名==> " + method.getDeclaringClass().getName());
        logger.info("方法名==> " + method.getName());

        // 不需要鉴权的直接放行
        if (uri.contains("api/0")) {
            return true;
        }

        SecureValid secureValid = handlerMethod.getMethod().getAnnotation(SecureValid.class);

        // 如果请求的处理方法上没有@SecureValid注解，说明是不需要验证的操作，直接放行让Controller处理
        if (CompareUtil.isEmpty(secureValid)) {
            return true;
        }

        String userName = (String) request.getSession().getAttribute(SessionKey.MODULE_ACCTNAME);

        // 未登录
        if (StringUtils.isEmpty(userName)) {
            String json = JSON.toJSONString(JSONReturn.buildFailure(LoginState.UNLOGIN.getMsg()));
            logger.info("返回的信息==> " + json);
            ResponseUtil.json(json, response);
            return false;
        }

        logger.info("个人所属角色对应的模块码是==> " + Arrays.asList(secureValid.code()).toString());
        logger.info("模块的描述==> " + secureValid.desc());
        logger.info("模块对应权限的类型==> " + secureValid.type());

        JitAccount jitAccount = accountService.findAccountByName(userName);
        // 不是系统用户，非法访问
        if (CompareUtil.isEmpty(jitAccount)) {
            String json = JSON.toJSONString(JSONReturn.buildFailure(LoginState.ILLEGAL_ACCESS.getMsg()));
            logger.info("返回的信息==> " + json);
            ResponseUtil.json(json, response);
            return false;
        }

        // 如果是超级管理员，直接放行让Controller处理
        if (jitAccount.getAcctSuper()) {
            return true;
        }

        // 权限不够
        if (!moduleService.secureValid(userName, secureValid.code(), secureValid.type())) {
            String json = JSON.toJSONString(JSONReturn.buildFailure(LoginState.PERMISSION_DENIED.getMsg()));
            logger.info("返回的信息==> " + json);
            ResponseUtil.json(json, response);
            return false;
        }

        return true;
    }
}
